#include "JctoSocket.h"

#if defined(_WIN32)

#include <winsock2.h>
#include <wspiapi.h>

#elif __APPLE__
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <sys/event.h>
#include <sys/types.h>
#elif __linux__

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#endif

void jctoSocketStart(void)
{
#if defined(_WIN32)
    {
        WSADATA wsd;
        WSAStartup(MAKEWORD(2,2),&wsd);
    }
#elif defined(__APPLE__)||defined(__linux__)
    signal(SIGPIPE,SIG_IGN);
#endif
}

JctoSocketStatus jctoSocketOpenTcp(JctoSocketHandle*handle,const char ip[],int port)
{
    (*handle)=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(-1==(*handle))
    {
        return JCTO_SOCKET_STATUS_START_FAILED;
    }
    int res;
    struct sockaddr_in stSockAddr;
    memset(&stSockAddr,0,sizeof(struct sockaddr_in));
    stSockAddr.sin_family=AF_INET;
    stSockAddr.sin_port=htons(port);
    res=inet_pton(AF_INET,ip,&stSockAddr.sin_addr);

    if(0>res)
    {
        return JCTO_SOCKET_STATUS_FAMILY_ERROR;
    }
    else if(0==res)
    {
        return JCTO_SOCKET_STATUS_IP_ERROR;
    }
    if(-1==connect((*handle),(const struct sockaddr*)&stSockAddr,sizeof(struct sockaddr_in)))
    {
        return JCTO_SOCKET_STATUS_CONNECT_ERROR;
    }
    return JCTO_SOCKET_STATUS_OK;
}

unsigned int jctoSocketSend(JctoSocketHandle*handle,const unsigned char data[],unsigned int len)
{
#if defined(_WIN32)
    return send(*handle,(const char*)data,len,0);
#elif defined(__APPLE__)||defined(__linux__)
    return send(*handle,(const char*)data,len,0);
#endif
}

int jctoSocketRecv(JctoSocketHandle*handle,unsigned char data[],unsigned int len)
{
#if defined(_WIN32)
    return recv(*handle,(char*)data,len,0);
#elif defined(__APPLE__)||defined(__linux__)
    return recv(*handle,(char*)data,len,0);
#endif
}

void jctoSocketClose(JctoSocketHandle*handle)
{
#if defined(_WIN32)
    closesocket(*handle);
#elif defined(__APPLE__)||defined(__linux__)
    close(*handle);
#endif
}
